package com.zhn.evsi.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhn.evsi.client.WalletClient;
import com.zhn.evsi.common.RedisCache;
import com.zhn.evsi.domain.dto.evsi.EvsiCharacterWalletJournalDTO;
import com.zhn.evsi.domain.dto.evsi.EvsiCharacterWalletTransactionsDTO;
import com.zhn.evsi.domain.dto.evsi.character.EvsiCharacterPublicInfoDTO;
import com.zhn.evsi.domain.entity.evsi.EvsiCharacterWallet;
import com.zhn.evsi.exception.CustomException;
import com.zhn.evsi.interceptor.CharacterInterceptor;
import com.zhn.evsi.mapper.EvsiCharacterWalletMapper;
import com.zhn.evsi.service.IEvsiCharacterWalletService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@Service
public class EvsiCharacterWalletServiceImpl extends ServiceImpl<EvsiCharacterWalletMapper, EvsiCharacterWallet> implements IEvsiCharacterWalletService {

    @Value("${eve.walletSize}")
    private Integer walletSize;
    @Resource
    private WalletClient walletClient;
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private CharacterInterceptor characterInterceptor;

    @Override
    @Transactional
    public Double wallet() {
        EvsiCharacterPublicInfoDTO characters = characterInterceptor.getCharacters(null);
        Double wallet = walletClient.wallet(characters.getCharacters());
        return wallet;
    }

    // 查询钱包余额并且将数据持久化
    @Override
    public Double saveWallet() {
        EvsiCharacterPublicInfoDTO characters = characterInterceptor.getCharacters(null);
        Double wallet = walletClient.wallet(characters.getCharacters());
        // 将金额存入mysql中
        EvsiCharacterWallet characterWallet = new EvsiCharacterWallet();
        characterWallet.setCharacterId(characters.getCharacters());
        characterWallet.setWallet(wallet);
        characterWallet.setCreateTime(new Date());
        boolean save = this.save(characterWallet);
        if (!save){
            throw new CustomException(characters + "保存钱包余额失败");
        }
        return wallet;
    }

    // 获取钱包交易记录
    @Override
    public Map<String, Object> journal() {
        String username = "1085155177@qq.com";
        List<EvsiCharacterWalletJournalDTO> characterWalletJournalList = new ArrayList<>();
        EvsiCharacterPublicInfoDTO characters = characterInterceptor.getCharacters(null);
        Integer walletSize = redisCache.getCacheObject("Account:WalletSize:" + username);
        if (ObjectUtil.isNull(walletSize)) {
            walletSize = this.walletSize;
        }
        Map<String, Object> map = redisCache.getCacheObject("Character:WalletJournal:" + characters.getCharacters());
        if (ObjectUtil.isNull(map)) {
            map = new HashMap<>();
            for (int i=1; i<100; i++) {
                List<EvsiCharacterWalletJournalDTO> journal = walletClient.journal(characters.getCharacters(), i);
                characterWalletJournalList.addAll(journal);

                if (journal.size() < 1000) {
                    break;
                }
            }
            List<EvsiCharacterWalletJournalDTO> limit = characterWalletJournalList.stream().limit(walletSize).collect(Collectors.toList());

            List<EvsiCharacterWalletJournalDTO> reverse = CollectionUtil.reverse(limit);

            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8"));

            String[] journalTime = reverse.stream().map(v -> {
                return simpleDateFormat.format(v.getDate());
            }).toArray(String[]::new);

            Double[] journalBalance = reverse.stream().map(EvsiCharacterWalletJournalDTO::getBalance).toArray(Double[]::new);
            Double[] journalAmount = reverse.stream().map(EvsiCharacterWalletJournalDTO::getAmount).toArray(Double[]::new);

            map.put("journalList", characterWalletJournalList);
            map.put("journalTime", journalTime);
            map.put("journalBalance", journalBalance);
            map.put("journalAmount", journalAmount);
            redisCache.setCacheObject("Character:WalletJournal:" + characters.getCharacters(), map, 2, TimeUnit.HOURS);
        }
        return map;
    }

    @Override
    public List<EvsiCharacterWalletTransactionsDTO> transactions() {
        EvsiCharacterPublicInfoDTO characters = characterInterceptor.getCharacters(null);
        List<EvsiCharacterWalletTransactionsDTO> characterWalletTransactionsDTOList = new ArrayList<>();

        List<JSONObject> transactions = walletClient.transactions(characters.getCharacters());
        transactions.forEach(v -> {
            characterWalletTransactionsDTOList.add(JSON.toJavaObject(v, EvsiCharacterWalletTransactionsDTO.class));
        });
        return characterWalletTransactionsDTOList;
    }
}
